/*
**
**		Heroes IV
**  Copyright 2001, The 3DO Company
**
**   dialog_mana_vortex.cpp
*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "dialog_mana_vortex.h"

#include <assert.h>
#include <limits>

#include "basic_dialog.h"
#include "bitmap_group.h"
#include "bitmap_group_cache.h"
#include "bitmap_group_window.h"
#include "bitmap_layer.h"
#include "bitmap_layer_window.h"
#include "blacksmith_window.h" // Just for k_creature_top_window_height (sigh)
#include "bound_handler.h"
#include "button.h"
#include "button_cache.h"
#include "creature_array.h"
#include "creature_array_window.h"
#include "external_string.h"
#include "format_string.h"
#include "game_replace_keywords.h"
#include "hero.h"
#include "interface_help.h"
#include "replace_keywords.h"
#include "standard_fonts.h"
#include "text_window.h"

t_bitmap_group_cache k_mana_vortex_bitmaps( "dialog.mana_vortex" );

extern  t_button_cache g_ok_button;
extern  t_button_cache g_cancel_button;
extern  t_bitmap_group_cache k_stat_icons_82;

/*
** Mana vortex dialog constructor.  Choose hero for spell point boost
*/
t_dialog_mana_vortex::t_dialog_mana_vortex ( t_window* parent )
					: t_window( k_completely_transparent, parent )
{
}

void t_dialog_mana_vortex::init_dialog( t_creature_array * main_hero_array,
								   t_creature_array * visiting_hero_array,
								   std::string const& name_text, 
								   std::string const& intro_text, 
								   std::string const& accepted_text )
{
	t_bitmap_layer const*   layer;
	t_window *              window;
	t_screen_point          origin(0,0);
	t_screen_rect           rect;
    int                     i;

	m_bitmaps_ptr = k_mana_vortex_bitmaps.get();
	layer = m_bitmaps_ptr->find( "background" );
	window = new t_bitmap_layer_window( layer, origin, this );

	assert( main_hero_array );

	if ( visiting_hero_array )
	{
		layer = m_bitmaps_ptr->find( "double_ring_background" );
		new t_bitmap_layer_window( layer, origin, this );

		t_screen_point point_first = m_bitmaps_ptr->find("hero_rings_double")->get_rect().top_left() + origin;

		t_screen_point point_second = point_first;
		point_second.y += k_creature_top_window_height;

		m_visiting_hero_window = new t_creature_array_window( point_second, visiting_hero_array, t_creature_array_window::k_bottom_row, 0, this );
		m_visiting_hero_window->set_select_handler( bound_handler( *this, &t_dialog_mana_vortex::hero_selection_change ) );
		m_visiting_hero_window->set_allow_drags( false );

		m_main_hero_window = new t_creature_array_window( point_first, main_hero_array, t_creature_array_window::k_top_row, 0, this );
		m_main_hero_window->set_select_handler( bound_handler( *this, &t_dialog_mana_vortex::hero_selection_change ) );
		m_main_hero_window->set_allow_drags( false );

		m_visiting_hero_window->link_selection( m_main_hero_window );
	}
	else
	{
		layer = m_bitmaps_ptr->find( "single_ring_background" );
		new t_bitmap_layer_window( layer, origin, this );

		t_screen_point point = m_bitmaps_ptr->find("hero_rings_single")->get_rect().top_left() + origin;
		m_main_hero_window = new t_creature_array_window( point, main_hero_array, t_creature_array_window::k_single_row, 0, this );
		m_main_hero_window->set_select_handler( bound_handler( *this, &t_dialog_mana_vortex::hero_selection_change ) );
	}


    /*
    ** Text windows.
    */
	t_text_window* text_window_ptr;
    
    // Title.
	rect = m_bitmaps_ptr->find( "title" )->get_rect() + origin;
	text_window_ptr = new t_text_window( get_font( 20 ), rect, this, name_text, t_pixel_24(0,0,0));
	text_window_ptr->set_center_horizontal();
	text_window_ptr->set_drop_shadow( false );

	/*
    ** Add the intro text.
    */
	m_intro_text = intro_text;
	rect = m_bitmaps_ptr->find( "text" )->get_rect() + origin;
	text_window_ptr = new t_text_window( get_font( 16 ), rect, this, m_intro_text, t_pixel_24(0,0,0));
	text_window_ptr->set_center_horizontal();
	text_window_ptr->set_drop_shadow( false );

	m_accepted_text = accepted_text;

    /*
    ** Show spell_points icon...this may change.
    */
	t_bitmap_group_ptr      stats_bitmaps_ptr = k_stat_icons_82.get();

	rect = m_bitmaps_ptr->find( "icon" )->get_rect() + origin;
	layer = stats_bitmaps_ptr->find( "spell_points" );
	window = new t_bitmap_layer_window( layer, rect.top_left(), this );
	
    /*
    ** Make window for spell icon text
    */
	rect = m_bitmaps_ptr->find( "icon_text" )->get_rect() + origin;
	m_icon_text_window_ptr = new t_text_window( get_font( 16 ), rect, this, "", t_pixel_24(0,0,0));
	m_icon_text_window_ptr->set_center_horizontal();
	m_icon_text_window_ptr->set_drop_shadow( false );

    /*
    ** Create buttons.
    */
	t_button            *button_ptr;
	t_help_block const&	   shared_help = get_help_block( "shared" );

	rect = m_bitmaps_ptr->find( "ok_button" )->get_rect();
	button_ptr = new t_button( g_ok_button.get(), rect.top_left(), this );
	button_ptr->set_click_handler( bound_handler( *this, &t_dialog_mana_vortex::close_click ));
  set_help( button_ptr, shared_help, "accept" );

	rect = m_bitmaps_ptr->find( "cancel_button" )->get_rect();
	button_ptr = new t_button( g_cancel_button.get(), rect.top_left(), this );
	button_ptr->set_click_handler( bound_handler( *this, &t_dialog_mana_vortex::cancel_click ));
  set_help( button_ptr, shared_help, "cancel" );
    
    /*
    ** Set the position and display the window.
    */
	t_screen_rect parent_rect = get_parent()->get_client_rect();
    
	rect = m_bitmaps_ptr->get_rect();
	rect += (parent_rect.size() - rect.size()) / 2;
	init( rect );

    // Select default hero. Default to hero with most to gain
	// Must be done AFTER window is set up
	t_creature_array_window * best_window = NULL;
	int best_index;
	int best_gain = std::numeric_limits<int>::min();
	for ( i = 0; i < t_creature_array::k_size; i++ )
	{
		t_hero * hero = (*main_hero_array)[i].get_hero();

		if ( hero )
		{
			int gain = (2 * hero->get_maximum_spell_points()) - hero->get_spell_points();

			if ( gain > best_gain )
			{
				best_gain = gain;
				best_index = i;
				best_window = m_main_hero_window;
			}
		}

		if ( visiting_hero_array )
		{
			t_hero * hero = (*visiting_hero_array)[i].get_hero();

			if ( hero )
			{
				int gain = (2 * hero->get_maximum_spell_points()) - hero->get_spell_points();

				if ( gain > best_gain )
				{
					best_gain = gain;
					best_index = i;
					best_window = m_visiting_hero_window;
				}
			}
		}
	}

	assert( best_window );

	if ( best_window )
	{
		best_window->select_creature( best_index );
	}
}

void t_dialog_mana_vortex::close_click( t_button* button )
{
	// Find selected hero
	t_hero * selected_hero = NULL;

	int selection = m_main_hero_window->get_selected_slot();
	if ( selection >= 0 )
	{
		selected_hero = (*m_main_hero_window->get_army())[selection].get_hero();
	}

	if ( m_visiting_hero_window != NULL && selected_hero == NULL )
	{
		selection = m_visiting_hero_window->get_selected_slot();
		if ( selection >= 0 )
		{
			selected_hero = (*m_visiting_hero_window->get_army())[selection].get_hero();
		}
	}

	if ( selected_hero == NULL )
	{
		// Treat as cancel
		m_return_value = false;
		close();
		return;
	}

	t_counted_ptr<t_basic_dialog> result_dialog = new t_basic_dialog;
	int max_mana = selected_hero->get_maximum_spell_points();

	int gain = (2 * max_mana) - selected_hero->get_spell_points();

	assert( gain > 0 );

    // Give hero double spell points. 
	selected_hero->set_spell_points( max_mana * 2 );

    // Show result dialog.
    result_dialog->set_text( m_accepted_text );
    result_dialog->add_ok_button();
	result_dialog->add_spell_points( gain );
    result_dialog->add_creature( *selected_hero, false );
    result_dialog->open();
    result_dialog->run_modal();

	m_return_value = true;
	close();
}

void t_dialog_mana_vortex::cancel_click( t_button* button )
{
	m_return_value = false;
	close();
}

static t_external_string const k_mana_vortex_dialog_icon_text("mana_vortex_dialog.icon_text");

void t_dialog_mana_vortex::hero_selection_change(  t_creature_array_window* selected_window, int selection )
{
    if ( selection < 0 )
	{
		m_icon_text_window_ptr->set_text( "" );
		return;
	}

	t_creature_array * army = selected_window->get_army();

	t_hero * hero = (*army)[selection].get_hero();

	if ( !hero )
	{
		m_icon_text_window_ptr->set_text( "" );
		return;
	}

	int gain = (2 * hero->get_maximum_spell_points()) - hero->get_spell_points();

	if ( gain < 0 )
		gain = 0;

	std::string gain_string = format_string( "%d", gain );

	m_icon_text_window_ptr->set_text( replace_keywords( k_mana_vortex_dialog_icon_text, "%gain", gain_string ) );
}

